package cn.com.nes.common.wx;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.nes.common.util.Globals;
import cn.com.nes.site.entity.AccessToken;

public class JsapiTicketScheduled {
	
	private static Logger log = LoggerFactory.getLogger(JsapiTicketScheduled.class);
	private static final long JSAPI_TICKET_SCHEDULED_TICK = 7000L;  
	private static volatile String accessToken =  getToken(Globals.WEIXIN_APPID,Globals.WEIXIN_APPSECRET).getAccessToken();
	private static volatile String jsapi_ticket = getJSApiTicket(accessToken);  
	private static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();  
	private static Connection conn = null;
		private static class TimerTicker implements Runnable  
		{  
	        @Override  
	        public void run()  
	        {  
	            //jsapi_ticket  
	        	accessToken  = getToken(Globals.WEIXIN_APPID,Globals.WEIXIN_APPSECRET).getAccessToken();
	            jsapi_ticket = getJSApiTicket(accessToken);  
	            try {
					saveAccessToken();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	            log.info("获取====================================================accessToken:" + accessToken +"jsapi_ticket:" + jsapi_ticket  );
	        }  
	    }  
	  
	    static  
	    {  
	    	
	    	 log.info("获取====================================================accessToken:" + accessToken +"jsapi_ticket:" + jsapi_ticket  );
	        //command - 要执行的任务  initialDelay - 首次执行的延迟时间    
	        //period - 连续执行之间的周期  unit - initialDelay 和 period 参数的时间单位   
	        executor.scheduleAtFixedRate(new TimerTicker(), JSAPI_TICKET_SCHEDULED_TICK,  
	        JSAPI_TICKET_SCHEDULED_TICK, TimeUnit.SECONDS);  
	        try {
				saveAccessToken();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        //shutdown hook  
	        Runtime.getRuntime().addShutdownHook(new Thread()  
	        {  
	            @Override  
	            public void run()  
	            {  
	                shutdownScheduledExecutor();  
	            }  
	        });  
	    }  
	  
	    /** 
	     * 返回全局的jsapi_ticket 
	     * @return  
	     * @see 
	     */  
	    public static String jsapiTicketScheduled()  
	    {  
	        return jsapi_ticket;  
	    }  
	    
	    
	    public static String accessTokenScheduled()
	    {
	    	return accessToken;
	    }
	  
	    /** 
	     * 关闭shutdownScheduledExecutor 
	     *   
	     * @see 
	     */  
	    public static void shutdownScheduledExecutor()  
	    {  
	        executor.shutdown();  
	    }  
	    public static  void saveAccessToken() throws SQLException {
	    	try {
	    		 conn = getDBConnect();
	    	        PreparedStatement ps = null;
	    			ResultSet rs = null;
	    			StringBuffer sb = new StringBuffer();
	    		sb.delete(0, sb.length());	
    			sb.append("insert into t_xtcs(`xzqhdm`, `csm`, `csz`, `cssm`, `bz`)"
						+ " values(?,?,?,?,?) on duplicate key update csz=?,cssm=?" );
			
			ps = conn.prepareStatement(sb.toString(),
					ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_UPDATABLE);
			ps.setString(1, "11");
			ps.setString(2, "accessToken");
			ps.setString(3, accessToken);
			ps.setString(4, jsapi_ticket);
			ps.setString(5, "accessToken");
			ps.setString(6, accessToken);
			ps.setString(7, jsapi_ticket);
			
			if (ps.executeUpdate() < 0) {
				conn.rollback();
				System.out.println("accessToken保存数据时出现错误!");
			}
	 		
			conn.commit();
	    	} finally {
	    	if (conn != null)
				conn.close();
		}
	    }
		public static Connection getDBConnect() {
			Connection conn = null;

			conn = getJndiDBConnect();
			if (conn == null) {
				System.out
						.println("********************************conn is null ********************************");
			}
			return conn;
		}

		public static Connection getJndiDBConnect() {
			Connection conn = null;
			try {
				Context initContext = new InitialContext();
				Context envContext = (Context) initContext.lookup("java:/comp/env");
				String jndi = "jdbc/ctce";
				DataSource ds = (DataSource) envContext.lookup(jndi);
				if (ds != null) {
					try {
						conn = ds.getConnection();
						conn.setAutoCommit(false);
						// System.err.println("JNDI 获取成功!");
					} catch (SQLException e) {
						System.err.println("JNDI 获取失败!");
					}
				}
			} catch (Exception e) {
				System.err.println("JNDI 获取失败!");
			}
			return conn;
		}
		public static AccessToken getToken(String appid, String appsecret) {
			  
			  AccessToken token = null;
			  String requestUrl = Globals.USER_TOKEN_URL_TEMPLATE.replace(
			    "#APPID#", appid).replace("#APPSECRET#", appsecret);
			  // 发起GET请求获取凭证
			  System.out.println(appid);
			  System.out.println(appsecret);
			  System.out.println(requestUrl);
			  JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);

			  if (null != jsonObject) {
			   try {
			    System.out.println(jsonObject.getString("access_token"));
			    System.out.println(jsonObject.getString("expires_in"));
			    
			    token = new AccessToken();
			    token.setAccessToken(jsonObject.getString("access_token"));
			    token.setExpiresIn(jsonObject.getInt("expires_in"));
			   } catch (JSONException e) {
			    e.printStackTrace() ;
			    token = null;
			    // 获取token失败
			    log.error("获取token失败 errcode:{} errmsg:{}",
			      jsonObject.getInt("errcode"),
			      jsonObject.getString("errmsg"));
			   }
			  }
			  return token;
			 }  
		public static String getJSApiTicket(String accessToken)
		{
				String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi"; 
				JSONObject jsonObject = CommonUtil.httpsRequest(urlStr, "GET", null);			
				String ticket ="";
				if (null != jsonObject) {
					try {
						ticket = jsonObject.getString("ticket");
					} catch (JSONException e) {
					}
				}
				
				return  ticket;  
		}
}

